/*****************************************************************************
 *  CommLayerLib for J2ME - BTDeviceSearch.java
 *  Copyright (C) 2012  Matteo Piscitelli
 *  E-mail: matteo@picciux.it
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 *  For further info, check http://code.google.com/p/java-comm-layer/
 *
 *  SVN: $Id: BTDeviceSearch.java 40 2012-10-10 19:54:31Z picciux@gmail.com $
 *  
 *****************************************************************************/

package it.picciux.commlayer.j2me.bluetooth;

import javax.bluetooth.*;

import java.util.Vector;

public class BTDeviceSearch {
	private Vector devsToScan;
	private Vector devsScanning;
	private Vector devs;
	
	private int maxSearches;
	
	private static final boolean DEBUG = false;
	
	public BTDeviceSearch(int maxSearches) {
		devsToScan = new Vector();
		devsScanning = new Vector();
		devs = new Vector();
		this.maxSearches = maxSearches;
		if (DEBUG) System.out.println("BTSS: max searches " + maxSearches);
	}

	public synchronized BTDevice addDevToScan(RemoteDevice rd) {
		BTDevice d = new BTDevice(rd);
		
		if (DEBUG) System.out.println("BTSS: " + devsScanning.size() + " devs scanning now");
		
		if (devsScanning.size() < maxSearches) {
			if (DEBUG) System.out.println("BTSS: add scanning device");
			vectorAddDev(devsScanning, d);
		} else {
			if (DEBUG) System.out.println("BTSS: limit reached: add waiting device");
			vectorAddDev(devsToScan, d);
			return null; //device scan delayed
		}
		
		return d;
	}
	
	public synchronized BTDevice scanNextDev() {
		if (devsToScan.size() == 0) {
			if (DEBUG) System.out.println("BTSS: no more dev to scan.");
			return null; // no more dev to scan
		}

		if (devsScanning.size() >= maxSearches) {
			if (DEBUG) System.out.println("BTSS: still can't add scanning device");
			return null; // delay scan
		}
		
		BTDevice d = (BTDevice) devsToScan.firstElement();
		devsToScan.removeElementAt(0);
		devsScanning.addElement(d);
		
		if (DEBUG) System.out.println("BTSS: one dev moved from queue to scan");
		if (DEBUG) System.out.println("BTSS: now " + devsScanning.size() + " scanning and " + 
				devsToScan.size() + " waiting");
		
		return d;
	}
	
	public synchronized BTDevice getScanningDev(int transID) {
		int i = vectorSearchTransID(devsScanning, transID);
		
		if (i == -1) return null;
		
		return (BTDevice) devsScanning.elementAt(i);
	}
	
	public synchronized int getWaitingDevsCount() {
		return devsToScan.size();
	}

	public synchronized int getScanningDevsCount() {
		return devsScanning.size();
	}
	
	public synchronized void discardDevice(BTDevice d) {
		vectorRemDev(devsScanning, d);
	}

	
	public synchronized void discardDevice(int transID) {
		if (DEBUG) System.out.println("BTSS: discarded one scanning device");
		vectorRemTransID(devsScanning, transID);
	}
	
	public synchronized BTDevice storeDevice(int transID) {
		int i = vectorSearchTransID(devsScanning, transID);

		if (i == -1) return null;
		
		BTDevice d = (BTDevice) devsScanning.elementAt(i);
		devsScanning.removeElementAt(i);
		devs.addElement(d);

		if (DEBUG) System.out.println("BTSS: one scanning device moved to store");
		return d;
	}
	
	public synchronized RemoteDevice[] getStoredDevs() {
		RemoteDevice[] ret = new RemoteDevice[devs.size()];
		
		for (int i = 0; i < ret.length; i++)
			ret[i] = ((BTDevice) devs.elementAt(i)).dev;
		
		return ret;
	}
	
	public synchronized void clearAll() {
		devsToScan.removeAllElements();
		devsScanning.removeAllElements();
		devs.removeAllElements();
		if (DEBUG) System.out.println("BTSS: cleared all");	
	}
	
	// privates
	
	private int vectorSearchDev(Vector v, BTDevice d) {
		int ret = -1;
		
		for (int i = 0; i < v.size(); i++)
			if (v.elementAt(i) == d) {
				ret = i;
				break;
			}
		
		return ret;
	}
	
	
	private int vectorSearchTransID(Vector v, int transID) {
		int ret = -1;
		
		for (int i = 0; i < v.size(); i++)
			if (((BTDevice) v.elementAt(i)).transID == transID) {
				ret = i;
				break;
			}
		
		return ret;
	}
	
	private void vectorAddDev(Vector v, BTDevice d) {
		v.addElement(d);
	}
	
	
	private void vectorRemDev(Vector v, BTDevice d) {
		int i = vectorSearchDev(v, d);
		if (i > -1) v.removeElementAt(i);
	}
	
	
	private void vectorRemTransID(Vector v, int transID) {
		int i = vectorSearchTransID(v, transID);
		if (i > - 1) v.removeElementAt(i);
	}
}
